/**
 * 注释节点
 * 文本节点
 * 元素节点
 * 组件节点
 * 函数式组件
 * 克隆节点
 * vnode是JS中的一个对象,不同类型的vnode之间也只是其中的有效属性不同.在实例化时,无效的属性会被赋值为undefined或者false
 */

/**注释节点 */
const createEmptyVNode = text => {
  const node = new Vnode();
  node.text = text;
  node.isComment = true;
  return node;
}
// 注释节点的有效属性只有text和isComment

/**文本节点 */
const createTextVNode = function (text) {
  return new Vnode(undefined, undefined, undefined, new String(text))
}
// 文本节点有效属性只有text

/**克隆节点就是将现有的节点的属性复制到新节点上,让新创建的节点和被克隆的节点的属性保持一致就行从而实现克隆效果 */
const createCloneVNode = function (vnode, deep) {
  const cloned = new Vnode(vnode.tag,
    vnode.data,
    vnode.children,
    vnode.text,
    vnode.elm,
    vnode.context,
    vnode.componmentOptions,
    vnode.asyncFactory
  )
  cloned.ns = vnode.ns
  cloned.isStatic = vnode.isStatic
  cloned.key = vnode.key
  cloned.isComment = vnode.isComment
  cloned.isCloned = true
  if (deep && vnode.children) {
    cloned.children = createCloneVNode(vnode.children)
  }
  return cloned
}
// 原始节点的isCloned时false,克隆出来的是true

/**元素节点 通常会存在以下4种有效属性:
 * tag          tag就是节点的名称   ul li p等
 * data         包含节点上的一些数据  class  style等等
 * children     节点的子节点列表
 * context      当前的vue.js实例
 * 一个真实的元素节点
 * <p><span>Hello</span><span>World</span></p>
 * 对应的vnode如下
 * {
 * children:[VNode,VNode],
 * context:{},
 * data:{},
 * tag:p
 * }
 */

/**
 * 组件节点   组件节点与元素节点类似   有两个以下的独特属性
 * commponentOptions :组件节点的选项参数  包含propsData,tag和children等信息
 * commponmentInstance  :组件的实例,也是Vue.js的实例.
 * 
 * <child></child>
 * 对应的vnode应该是
 * {
 * commponentOptions:{}
 * commponmentInstance:{}
 * context:{}
 * data:{}
 * tag:vue-component-1-child
 * }
 */

/**函数式组件    与组件节点类似,他有两个独特的属性 functionalContext和functionalOptions
 * 
 * 一个函数式组件的vnode应该是
 * {
 * functionalContext:{}
 * functionalOptions:{}
 * context:{}
 * data:{}
 * tag:div
 * }
 */